package com.ntanh.mealplanner.main.planner;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.ntanh.mealplanner.R;
import com.ntanh.mealplanner.base.model.BaseEntity;
import com.ntanh.mealplanner.base.model.NamedEntity;
import com.ntanh.mealplanner.main.FragmentRecipe;
import com.ntanh.mealplanner.main.MainActivity;
import com.ntanh.mealplanner.main.dao.DataBaseHelper;
import com.ntanh.mealplanner.main.dao.DayMealDao;
import com.ntanh.mealplanner.main.dao.MealDao;
import com.ntanh.mealplanner.main.dao.WeekMealDao;
import com.ntanh.mealplanner.main.objects.DayMeal;
import com.ntanh.mealplanner.main.objects.Meal;
import com.ntanh.mealplanner.main.objects.MealType;
import com.ntanh.mealplanner.main.objects.Recipe;
import com.ntanh.mealplanner.main.objects.WeekMeal;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

public class FragmentPlanner extends Fragment {

    public static final Integer FRAGMENT_ICON = R.drawable.ic_planner;
    public static final Integer FRAGMENT_NAME = R.string.meal_planner;
    public static final Integer ADD_RECIPE = 1;

    public static final int ADD_RECIPE_REQUEST = 1;

    private Context context;
    private int selectedGroupPosition;
    private Date weekStartDate;
    private Calendar calendar;

    private DayMealExpandableListAdapter listAdapter;
    private ExpandableListView expListView;
    private List<DayMeal> listDataHeader;
    private HashMap<DayMeal, List<BaseEntity>> listDataChild;

    private MealDao mealDao;
    private DayMealDao dayMealDao;
    private WeekMealDao weekMealDao;

    public FragmentPlanner() {
        selectedGroupPosition = -1;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        final View view = inflater.inflate(R.layout.fragment_layout_planner, container, false);

        calendar = Calendar.getInstance(getResources().getConfiguration().locale);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        weekStartDate = calendar.getTime();

        context = view.getContext();
        mealDao = new MealDao(context);
        dayMealDao = new DayMealDao(context);
        weekMealDao = new WeekMealDao(context);

        // get the listview
        expListView = (ExpandableListView) view.findViewById(R.id.expLvDayMeal);
        // preparing list data
        prepareListData();
        listAdapter = new DayMealExpandableListAdapter(context, listDataHeader, listDataChild);
        // setting list adapter
        expListView.setAdapter(listAdapter);
        // Listview Group click listener
        expListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                final DayMeal dayMeal = listDataHeader.get(groupPosition);

                final Dialog dialog = new Dialog(context);
                dialog.setContentView(R.layout.day_meal_dialog);
                dialog.setTitle(R.string.meal_type);

                List<MealType> types = MealType.loadFromConfigFile(context);
                DayMealDialogLvAdapter adapter = new DayMealDialogLvAdapter(context, R.layout.day_meal_dialog_list_type, types);

                ListView lv = (ListView) dialog.findViewById(R.id.lvDayMealDialog);
                lv.setAdapter(adapter);
                lv.setOnItemClickListener(new ListView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        Intent intent = new Intent(context, AddRecipeActivity.class);
                        List<MealType> types = MealType.loadFromConfigFile(getActivity().getApplicationContext());
                        boolean flag = true;
                        for (Meal meal : dayMeal.getMealList()) {
                            if (meal.getType().equals(types.get(position))) {
                                intent.putExtra("mealId", meal.getId());
                                flag = false;
                                break;
                            }
                        }
                        if (flag) {
                            Meal meal = new Meal("author",  types.get(position));
                            mealDao.save(meal);
                            dayMeal.getMealList().add(meal);
                            Collections.sort(dayMeal.getMealList());
                            dayMealDao.update(dayMeal);
                            intent.putExtra("mealId", meal.getId());
                        }
                        dialog.cancel();
                        startActivityForResult(intent, ADD_RECIPE_REQUEST);
                    }
                });
                dialog.show();
                selectedGroupPosition = groupPosition;
                return true;
            }
        });

        // Listview Group expanded listener
        expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                //Toast.makeText(context, listDataHeader.get(groupPosition) + " Expanded", Toast.LENGTH_SHORT).show();
            }
        });
        // Listview Group collasped listener
        expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {
                //Toast.makeText(context, listDataHeader.get(groupPosition) + " Collapsed", Toast.LENGTH_SHORT).show();
            }
        });
        // Listview on child click listener
        expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                //Toast.makeText(context, listDataHeader.get(groupPosition) + " : " + listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition), Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        //Week
        ImageView next = (ImageView) view.findViewById(R.id.nextWeek);
        ImageView previous = (ImageView) view.findViewById(R.id.previousWeek);
        final TextView weekTitle = (TextView) view.findViewById(R.id.weekTitle);
        ImageView save = (ImageView) view.findViewById(R.id.saveWeekMeal);
        ImageView share = (ImageView) view.findViewById(R.id.shareMeal);
        ImageView search = (ImageView) view.findViewById(R.id.searchRecipe);
        ImageView menu = (ImageView) view.findViewById(R.id.mealMenu);

        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar cal = Calendar.getInstance();
                cal.setTime(weekStartDate);
                cal.add(Calendar.DATE, 7);
                weekStartDate = cal.getTime();
                prepareListData();
                listAdapter.notifyDataSetChanged();
                weekTitle.setText(getWeekTitle(weekStartDate));
            }
        });

        previous.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar cal = Calendar.getInstance();
                cal.setTime(weekStartDate);
                cal.add(Calendar.DATE, -7);
                weekStartDate = cal.getTime();
                prepareListData();
                listAdapter.notifyDataSetChanged();
                weekTitle.setText(getWeekTitle(weekStartDate));
            }
        });

        weekTitle.setText(getWeekTitle(weekStartDate));

        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Dialog dialog = new Dialog(context);
                dialog.setContentView(R.layout.save_week_meal_dialog);
                dialog.setTitle(R.string.save_week_meal);

                Button ok = (Button) dialog.findViewById(R.id.saveWeekMealDiaOk);
                Button cancel = (Button) dialog.findViewById(R.id.saveWeekMealDiaCancel);
                final EditText etName = (EditText) dialog.findViewById(R.id.saveWeekMealDiaName);

                ok.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String name = etName.getText().toString();
                        boolean isUpdate = true;
                        WeekMeal wm = weekMealDao.getByName("", name);
                        if(wm == null){
                            wm = new WeekMeal("author", name, weekStartDate);
                            isUpdate = false;
                        }
                        wm.getDayMealList().clear();
                        wm.setDayMealList(listDataHeader);
                        if(isUpdate){
                            weekMealDao.update(wm);
                        } else {
                            weekMealDao.save(wm);
                        }
                        dialog.cancel();
                    }
                });

                cancel.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.cancel();
                    }
                });

                dialog.show();
            }
        });

        return view;
    }

    private String getWeekTitle(Date newDate) {
        Date today = new Date();
        calendar.setTime(today);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        Date startWeek = calendar.getTime();
        long milliseconds = startWeek.getTime() - newDate.getTime();
        long range = TimeUnit.DAYS.convert(milliseconds, TimeUnit.MILLISECONDS);

        String title = "";
        if (0 <= range && range < 7) {
            title = getString(R.string.current_week);
        } else if (range >= 7 && range < 14) {
            title = getString(R.string.previous_week);
        } else if (range >= -6 && range < 0) {
            title = getString(R.string.next_week);
        } else if (range < -6) {
            int count = 1;
            while (range < -6) {
                range += 7;
                count += 1;
            }
            title = "+" + count + " " + getString(R.string.week);
        } else if (range >= 14) {
            int count = 1;
            while (range >= 14) {
                range -= 7;
                count += 1;
            }
            title = "-" + count + " " + getString(R.string.week);
        }

        return title;
    }

    /*
     * Preparing the list data
     */
    public void prepareListData() {
        if (listDataHeader == null) {
            listDataHeader = new ArrayList<DayMeal>();
        } else {
            listDataHeader.clear();
        }
        if (listDataChild == null) {
            listDataChild = new HashMap<DayMeal, List<BaseEntity>>();
        } else {
            listDataChild.clear();
        }

        DayMealDao dayMealDao = new DayMealDao(context);
        calendar.setTime(weekStartDate);
        for (int i = 0; i < 7; i++) {
            calendar.set(Calendar.DAY_OF_WEEK, (2 + i) % 7);
            Date date = calendar.getTime();
            DayMeal dayMeal = dayMealDao.getByDate("author", date);
            if (dayMeal == null) {
                dayMeal = new DayMeal("author", date);
                dayMealDao.save(dayMeal);
            } else {
                if (dayMeal.getMealList() != null) {
                    List<BaseEntity> list = new ArrayList<BaseEntity>();
                    for (Meal meal : dayMeal.getMealList()) {
                        list.add(meal);
                        if (meal.getRecipeList() != null) {
                            for (Recipe recipe : meal.getRecipeList()) {
                                list.add(recipe);
                            }
                        }
                    }
                    listDataChild.put(dayMeal, list);
                }
            }
            listDataHeader.add(dayMeal);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case ADD_RECIPE_REQUEST:
                prepareListData();
                listAdapter.notifyDataSetChanged();
                if (selectedGroupPosition > -1) {
                    expListView.expandGroup(selectedGroupPosition);
                    selectedGroupPosition = -1;
                }
                break;
            default:
                break;
        }
    }
}